// 视觉效果系统 - Stage 3
import { GameConfig } from '../config/GameConfig.js';

// 粒子类型枚举
export enum ParticleType {
    EXPLOSION = 'explosion',
    SMOKE = 'smoke',
    FIRE = 'fire',
    SPARK = 'spark',
    DEBRIS = 'debris',
    TRAIL = 'trail',
    SHOCKWAVE = 'shockwave',
    INTERCEPT_FLASH = 'intercept_flash'
}

// 粒子接口
interface Particle {
    id: string;
    type: ParticleType;
    x: number;
    y: number;
    vx: number;
    vy: number;
    life: number;
    maxLife: number;
    size: number;
    color: string;
    alpha: number;
    rotation: number;
    rotationSpeed: number;
    gravity: number;
    active: boolean;
}

// 粒子系统配置
interface ParticleSystemConfig {
    maxParticles: number;
    emissionRate: number;
    lifespan: number;
    lifespanVariation: number;
    speed: number;
    speedVariation: number;
    size: number;
    sizeVariation: number;
    colors: string[];
    gravity: number;
    spread: number;
    fadeOut: boolean;
    shrink: boolean;
}

// 预定义粒子效果配置
const PARTICLE_CONFIGS: Record<ParticleType, ParticleSystemConfig> = {
    [ParticleType.EXPLOSION]: {
        maxParticles: 50,
        emissionRate: 50,
        lifespan: 2000,
        lifespanVariation: 500,
        speed: 200,
        speedVariation: 100,
        size: 8,
        sizeVariation: 4,
        colors: ['#ff6b35', '#f7931e', '#ffdc00', '#ff0000'],
        gravity: 50,
        spread: Math.PI * 2,
        fadeOut: true,
        shrink: true
    },
    [ParticleType.SMOKE]: {
        maxParticles: 30,
        emissionRate: 15,
        lifespan: 3000,
        lifespanVariation: 1000,
        speed: 50,
        speedVariation: 25,
        size: 12,
        sizeVariation: 6,
        colors: ['#666666', '#888888', '#aaaaaa'],
        gravity: -20,
        spread: Math.PI / 3,
        fadeOut: true,
        shrink: false
    },
    [ParticleType.FIRE]: {
        maxParticles: 25,
        emissionRate: 20,
        lifespan: 1500,
        lifespanVariation: 300,
        speed: 80,
        speedVariation: 40,
        size: 6,
        sizeVariation: 3,
        colors: ['#ff6b35', '#f7931e', '#ffdc00'],
        gravity: -100,
        spread: Math.PI / 4,
        fadeOut: true,
        shrink: true
    },
    [ParticleType.SPARK]: {
        maxParticles: 40,
        emissionRate: 40,
        lifespan: 1000,
        lifespanVariation: 200,
        speed: 300,
        speedVariation: 150,
        size: 3,
        sizeVariation: 1,
        colors: ['#ffdc00', '#ffffff', '#ffa500'],
        gravity: 200,
        spread: Math.PI * 2,
        fadeOut: true,
        shrink: false
    },
    [ParticleType.DEBRIS]: {
        maxParticles: 20,
        emissionRate: 20,
        lifespan: 3000,
        lifespanVariation: 1000,
        speed: 150,
        speedVariation: 75,
        size: 4,
        sizeVariation: 2,
        colors: ['#8b4513', '#a0522d', '#696969'],
        gravity: 300,
        spread: Math.PI,
        fadeOut: false,
        shrink: false
    },
    [ParticleType.TRAIL]: {
        maxParticles: 10,
        emissionRate: 10,
        lifespan: 800,
        lifespanVariation: 200,
        speed: 20,
        speedVariation: 10,
        size: 5,
        sizeVariation: 2,
        colors: ['#ffffff', '#e0e0e0'],
        gravity: 0,
        spread: Math.PI / 6,
        fadeOut: true,
        shrink: true
    },
    [ParticleType.SHOCKWAVE]: {
        maxParticles: 1,
        emissionRate: 1,
        lifespan: 500,
        lifespanVariation: 0,
        speed: 0,
        speedVariation: 0,
        size: 20,
        sizeVariation: 0,
        colors: ['#ffffff'],
        gravity: 0,
        spread: 0,
        fadeOut: true,
        shrink: false
    },
    [ParticleType.INTERCEPT_FLASH]: {
        maxParticles: 15,
        emissionRate: 15,
        lifespan: 600,
        lifespanVariation: 100,
        speed: 100,
        speedVariation: 50,
        size: 4,
        sizeVariation: 2,
        colors: ['#00ff00', '#ffffff', '#90ee90'],
        gravity: 0,
        spread: Math.PI * 2,
        fadeOut: true,
        shrink: true
    }
};

export class VisualEffectsSystem {
    private particles: Particle[] = [];
    private particlePool: Particle[] = [];
    private nextParticleId = 0;
    private ctx: CanvasRenderingContext2D;

    constructor(ctx: CanvasRenderingContext2D) {
        this.ctx = ctx;
        this.initializeParticlePool();
    }

    private initializeParticlePool(): void {
        // 预分配粒子池，减少GC压力
        for (let i = 0; i < 500; i++) {
            this.particlePool.push(this.createParticle());
        }
        console.log('✨ 视觉效果系统初始化完成，粒子池大小:', this.particlePool.length);
    }

    private createParticle(): Particle {
        return {
            id: `particle_${this.nextParticleId++}`,
            type: ParticleType.EXPLOSION,
            x: 0,
            y: 0,
            vx: 0,
            vy: 0,
            life: 0,
            maxLife: 1000,
            size: 5,
            color: '#ffffff',
            alpha: 1,
            rotation: 0,
            rotationSpeed: 0,
            gravity: 0,
            active: false
        };
    }

    private getParticleFromPool(): Particle | null {
        const particle = this.particlePool.pop();
        if (particle) {
            particle.active = true;
            return particle;
        }
        return null;
    }

    private returnParticleToPool(particle: Particle): void {
        particle.active = false;
        this.particlePool.push(particle);
    }

    public createEffect(type: ParticleType, x: number, y: number, intensity: number = 1): void {
        const config = PARTICLE_CONFIGS[type];
        if (!config) return;

        const particleCount = Math.floor(config.maxParticles * intensity);

        for (let i = 0; i < particleCount; i++) {
            const particle = this.getParticleFromPool();
            if (!particle) break;

            // 基础属性
            particle.type = type;
            particle.x = x;
            particle.y = y;
            
            // 随机速度和方向
            const angle = (config.spread * Math.random()) - (config.spread / 2);
            const speed = config.speed + (Math.random() - 0.5) * config.speedVariation;
            particle.vx = Math.cos(angle) * speed;
            particle.vy = Math.sin(angle) * speed;
            
            // 生命周期
            particle.maxLife = config.lifespan + (Math.random() - 0.5) * config.lifespanVariation;
            particle.life = particle.maxLife;
            
            // 视觉属性
            particle.size = config.size + (Math.random() - 0.5) * config.sizeVariation;
            particle.color = config.colors[Math.floor(Math.random() * config.colors.length)];
            particle.alpha = 1;
            particle.rotation = Math.random() * Math.PI * 2;
            particle.rotationSpeed = (Math.random() - 0.5) * 5;
            particle.gravity = config.gravity;

            this.particles.push(particle);
        }

        // 特殊效果处理
        if (type === ParticleType.SHOCKWAVE) {
            this.createShockwave(x, y, intensity);
        }
    }

    private createShockwave(x: number, y: number, intensity: number): void {
        const particle = this.getParticleFromPool();
        if (!particle) return;

        particle.type = ParticleType.SHOCKWAVE;
        particle.x = x;
        particle.y = y;
        particle.vx = 0;
        particle.vy = 0;
        particle.maxLife = 500;
        particle.life = 500;
        particle.size = 10;
        particle.color = '#ffffff';
        particle.alpha = 0.8;
        particle.rotation = 0;
        particle.rotationSpeed = 0;
        particle.gravity = 0;

        this.particles.push(particle);
    }

    public update(deltaTime: number): void {
        for (let i = this.particles.length - 1; i >= 0; i--) {
            const particle = this.particles[i];
            
            // 更新生命周期
            particle.life -= deltaTime;
            if (particle.life <= 0) {
                this.particles.splice(i, 1);
                this.returnParticleToPool(particle);
                continue;
            }

            // 更新位置
            particle.x += particle.vx * deltaTime / 1000;
            particle.y += particle.vy * deltaTime / 1000;
            
            // 应用重力
            particle.vy += particle.gravity * deltaTime / 1000;
            
            // 更新旋转
            particle.rotation += particle.rotationSpeed * deltaTime / 1000;
            
            // 更新视觉属性
            const lifeRatio = particle.life / particle.maxLife;
            const config = PARTICLE_CONFIGS[particle.type];
            
            if (config.fadeOut) {
                particle.alpha = lifeRatio;
            }
            
            if (config.shrink && particle.type !== ParticleType.SHOCKWAVE) {
                particle.size *= 0.995;
            }
            
            // 冲击波特殊处理
            if (particle.type === ParticleType.SHOCKWAVE) {
                particle.size += deltaTime * 0.3; // 冲击波扩散
                particle.alpha = lifeRatio * 0.8;
            }
        }
    }

    public render(): void {
        this.ctx.save();

        for (const particle of this.particles) {
            this.ctx.save();
            
            // 设置透明度
            this.ctx.globalAlpha = particle.alpha;
            
            // 移动到粒子位置
            this.ctx.translate(particle.x, particle.y);
            this.ctx.rotate(particle.rotation);
            
            // 渲染不同类型的粒子
            this.renderParticle(particle);
            
            this.ctx.restore();
        }

        this.ctx.restore();
    }

    private renderParticle(particle: Particle): void {
        switch (particle.type) {
            case ParticleType.SHOCKWAVE:
                this.renderShockwave(particle);
                break;
            case ParticleType.TRAIL:
                this.renderTrail(particle);
                break;
            default:
                this.renderCircleParticle(particle);
                break;
        }
    }

    private renderCircleParticle(particle: Particle): void {
        this.ctx.fillStyle = particle.color;
        this.ctx.beginPath();
        this.ctx.arc(0, 0, particle.size, 0, Math.PI * 2);
        this.ctx.fill();
    }

    private renderShockwave(particle: Particle): void {
        this.ctx.strokeStyle = particle.color;
        this.ctx.lineWidth = 2;
        this.ctx.beginPath();
        this.ctx.arc(0, 0, particle.size, 0, Math.PI * 2);
        this.ctx.stroke();
    }

    private renderTrail(particle: Particle): void {
        this.ctx.fillStyle = particle.color;
        this.ctx.beginPath();
        this.ctx.ellipse(0, 0, particle.size, particle.size * 0.3, 0, 0, Math.PI * 2);
        this.ctx.fill();
    }

    public createMissileExplosion(x: number, y: number): void {
        this.createEffect(ParticleType.EXPLOSION, x, y, 1.2);
        this.createEffect(ParticleType.FIRE, x, y, 0.8);
        this.createEffect(ParticleType.SMOKE, x, y, 0.6);
        this.createEffect(ParticleType.SPARK, x, y, 1.0);
        this.createEffect(ParticleType.SHOCKWAVE, x, y, 1.0);
    }

    public createInterceptExplosion(x: number, y: number): void {
        this.createEffect(ParticleType.INTERCEPT_FLASH, x, y, 1.0);
        this.createEffect(ParticleType.SPARK, x, y, 0.7);
        this.createEffect(ParticleType.SHOCKWAVE, x, y, 0.8);
    }

    public createMissileTrail(x: number, y: number): void {
        this.createEffect(ParticleType.TRAIL, x, y, 0.3);
    }

    public createDebrisEffect(x: number, y: number): void {
        this.createEffect(ParticleType.DEBRIS, x, y, 0.8);
        this.createEffect(ParticleType.SMOKE, x, y, 0.4);
    }

    public getActiveParticleCount(): number {
        return this.particles.length;
    }

    public clearAllParticles(): void {
        while (this.particles.length > 0) {
            const particle = this.particles.pop()!;
            this.returnParticleToPool(particle);
        }
    }
}
